<template>
   <div>
      <!-- @close 事件 点击关闭时也是触发调用取消 隐藏弹层 -->
      <el-dialog
         :title="showTitle"
         :visible="showDialog"
         @close="btnCancel"
      >
         <el-form
            label-width="120px"
            :model="formData"
            :rules="rules"
            ref="deptForm"
         >
            <el-form-item label="部门名称" prop="name">
               <el-input
                  style="width:80%"
                  placeholder="1-50个字符"
                  v-model="formData.name"
               ></el-input>
            </el-form-item>
            <el-form-item label="部门编码" prop="code">
               <el-input
                  style="width:80%"
                  placeholder="1-50个字符"
                  v-model="formData.code"
               ></el-input>
            </el-form-item>
            <el-form-item label="部门负责人" prop="manager">
               <!-- focus 聚焦事件 -->
               <el-select
                  @focus="getEmployeeSimple"
                  style="width:80%"
                  placeholder="请选择"
                  v-model="formData.manager"
               >
                  <!-- 遍历选项 -->
                  <el-option
                     v-for="item in peoples"
                     :key="item.id"
                     :label="item.username"
                     :value="item.username"
                  ></el-option>
               </el-select>
            </el-form-item>
            <el-form-item label="部门介绍" prop="introduce">
               <el-input
                  style="width:80%"
                  placeholder="1-300个字符"
                  type="textarea"
                  :rows="3"
                  v-model="formData.introduce"
               ></el-input>
            </el-form-item>
         </el-form>
         <!-- 底部 确定跟取消 -->
         <el-row type="flex" justify="center" slot="footer">
            <el-col :span="6">
               <el-button type="primary" size="small" @click="btnOK">
                  确定
               </el-button>
               <el-button size="small" @click="btnCancel">取消</el-button>
            </el-col>
         </el-row>
      </el-dialog>
   </div>
</template>

<script>
import {
   getDepartments,
   addDepartments,
   getDepartDetail,
   updateDepartments
} from '../../../api/departments'
import { getEmployeeSimple } from '../../../api/employees'
export default {
   props: {
      showDialog: {
         type: Boolean,
         default: false
      },
      treeNode: {
         type: Object,
         default: null
      }
   },
   data() {
      // 检查部门名称是否重复
      // 要同时支持新增跟编辑的校验规则
      
      const checkNameRepeat = async (rule, value, callback) => {
         // value 是部门名称，要和同级部门去比较，有没有相同的，
         // 有相同不能过 ， 不相同可以过
         // 校验的时候获取最新数据
         // depts 获取所有部门数据的数组  每次获取最新数据
         const { depts } = await getDepartments()
         var isRepeat = false
         if (this.formData.id) {
            // 有 id 就是编辑模式
            // 编辑的数据在数据库中有，同级部门下，
            // 名字不能和其他的同级部门的名字进行重复
            // 先要找到同级部门  this.formData.id 就是我当前的 id
            // 我的 pid 是 this.formData.pid
            // 找谁的 pid 和我的 pid 一样
            // depts.filter(item => item.pid === this.formData.pid)
            // 找到了同级部门下除了我之外的所有的部门,在这个基础之上，
            // 找有没有人的name 跟我的name 一样
            isRepeat = depts
               .filter(
                  item =>
                     item.pid === this.treeNode.pid &&
                     item.id !== this.treeNode.id
               )
               .some(item => item.name === value)
         } else {
            // 没有id 就是新增模式
            // 去找同级部门下有没有跟 value 相同的数据
            // 找到所有的子部门
            // 子节点的 pid === 当前节点的 id   filter 筛选一下
            isRepeat = depts
               .filter(item => item.pid === this.treeNode.id)
               .some(item => item.name === value)
         }

         // 如果为 true 表示找到了一样的名字
         isRepeat
            ? callback(new Error(`同级部门下已经存在这个${value}部门了`))
            : callback()
      }
      const checkCodeRepeat = async (rule, value, callback) => {
         const { depts } = await getDepartments()
         var isRepeat = false
         if (this.formData.id) {
            // 有 id 编辑模式
            // 要求不能有一样的 code,把自己排除去跟别人比
            isRepeat = depts
               .filter(item => item.id !== this.treeNode.id)
               .some(item => item.code === value && value)
         } else {
            // 新增模式
            // 要求编码 和所有的部门编码不能重复 ，
            // 由于历史数据有可能 没有code,这里家一个强制性条件，value 不为空
            isRepeat = depts.some(item => item.code === value && value)
         }

         isRepeat
            ? callback(new Error(`组织架构下已经存在这个${value}编码了`))
            : callback()
      }
      return {
         // 定义一个表单数据
         formData: {
            // 名称
            name: '',
            // 编码
            code: '',
            // 管理者
            manager: '',
            // 介绍
            introduce: ''
         },
         // 校验规则
         rules: {
            // 名称
            name: [
               {
                  required: true,
                  message: '部门名称不能为空',
                  trigger: 'blur'
               },
               {
                  min: 1,
                  max: 50,
                  message: '部门名称长度为1-50个字符',
                  trigger: 'blur'
               },
               {
                  trigger: 'blur',
                  validator: checkNameRepeat
               }
            ],
            // 编码
            code: [
               {
                  required: true,
                  message: '部门编码不能为空',
                  trigger: 'blur'
               },
               {
                  min: 1,
                  max: 50,
                  message: '部门编码长度为1-50个字符',
                  trigger: 'blur'
               },
               {
                  trigger: 'blur',
                  validator: checkCodeRepeat
               }
            ],
            // 管理者
            manager: [
               {
                  required: true,
                  message: '部门负责人不能为空',
                  trigger: 'blur'
               }
            ],
            // 介绍
            introduce: [
               {
                  required: true,
                  message: '部门介绍不能为空',
                  trigger: 'blur'
               },
               {
                  min: 1,
                  max: 300,
                  message: '部门介绍长度为1-300个字符',
                  trigger: 'blur'
               }
            ]
         },
         peoples: []
      }
   },
   computed: {
      showTitle() {
         return this.formData.id ? '编辑部门' : '新增子部门'
      }
   },
   methods: {
      async getEmployeeSimple() {
         const result = await getEmployeeSimple()
         this.peoples = result
      },
      // 确定的方法
      btnOK() {
         // 手动校验表单
         this.$refs.deptForm.validate(async isOK => {
            if (isOK) {
               // 通过校验之后，在点击确定时，同时支持新增部门和编辑部门两个场景
               if (this.formData.id) {
                  // 如果有id 就是编辑
                  // 因为是编辑。是对当前现有的数据的修改
                  await updateDepartments(this.formData)
               } else {
                  // 没有id就是新增
                  // 表单校验通过
                  // 这里我们将 id 设成了我的 pid
                  await addDepartments({
                     ...this.formData,
                     pid: this.treeNode.id
                  })
               }

               //  告诉父组件， 拉去最新的数据
               this.$emit('addDepts')
               // 此时修改 showDialog 的值
               this.$emit('update:showDialog', false)
               // 点击确定关闭 dialog 的时候，会触发 el-dialog的 close 事件
               // close 会调用 btnCancel，会重置字段
               // 所以这里不需要单独的重置数据了
            }
         })
      },
      // 取消的方法
      // resetFields  对整个表单进行重置，将所有字段值重置为初始值并移除校验结果
      // 也把 formData 的数据还原了
      btnCancel() {
         // 重置数据  因为 resetFields 只能重置表单上的数据，
         // 非表单上的 比如 编辑中的 id 不能重置
         // 前一个场景，可以，两个合在一起不可以
         this.formData = {
            // 名称
            name: '',
            // 编码
            code: '',
            // 管理者
            manager: '',
            // 介绍
            introduce: ''
         }
         // 关闭弹层
         this.$emit('update:showDialog', false)
         // 清除之前的校验（就是点击确定验证之后关闭弹层，
         // 在点击出现的是清除完校验的弹层）
         // resetFields 重置数据，只能重置 定义在 data 中的数据
         this.$refs.deptForm.resetFields()
      },
      // 获取详情方法
      async getDepartDetail(id) {
         // 把 formData 的数据显示在页面上
         // 回写：把获取的数据给到 formData 中
         this.formData = await getDepartDetail(id)
         // 因为是父组件调用子组件的方法，刚设置完了 node 数据，node 是有值的，
         // 但是 props 传值是异步的 直接调用方法
         // 可以通过方法传递过来一个 id ，避免异步
      }
   }
}
</script>

<style lang="sass" scoped></style>
